/**
 * 
 */
package net.toocruel.iqismart.entity.rbac;

import net.toocruel.iqismart.entity.base.BaseEntity;
import net.toocruel.iqismart.entity.constants.ResourceType;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import springfox.documentation.annotations.ApiIgnore;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 需要控制权限的资源，以业务人员能看懂的name呈现.实际关联到一个或多个url上。
 * 
 * 树形结构。
 * 
 * @author toocruel
 *
 */
@Entity
public class Resource extends BaseEntity {

	private static final long serialVersionUID = -6033406361503688138L;
	/**
	 * 资源名称，如xx菜单，xx按钮
	 */
	private String name;
	/**
	 * 资源链接
	 */
	private String link;
	/**
	 * 图标
	 */
	private String icon;
	/**
	 * 资源类型
	 */
	@Enumerated(EnumType.STRING)
	private ResourceType type;
	/**
	 * 实际需要控制权限的url
	 */
	@ElementCollection(fetch = FetchType.EAGER)
	@JoinTable(name = "resource_url",joinColumns = @JoinColumn(name = "resourceId"))
	private Set<String> urls;
	/**
	 * 父资源
	 */
	@ManyToOne(cascade = { CascadeType.MERGE}, optional=true)
	@JoinColumn(name = "parentId")
	private Resource parent;
	/**
	 * 子资源
	 */
	@OneToMany(cascade = { CascadeType.ALL}, fetch=FetchType.LAZY, mappedBy="parent")
	@OrderBy("sort ASC")
	private List<Resource> childs = new ArrayList<>();

	public Resource() {
	}

	public Resource(String name, String link, String icon, ResourceType type, Set<String> urls, Resource parent) {
		this.name = name;
		this.link = link;
		this.icon = icon;
		this.type = type;
		this.urls = urls;
		this.parent = parent;
	}

	public Resource toTree(User user) {
		Resource resource = new Resource();
		BeanUtils.copyProperties(this, resource);
		Set<Long> resourceIds = user.getAllResourceIds();
		
		List<Resource> children = new ArrayList<Resource>();
		for (Resource child : getChilds()) {
			//判断用户是否拥有当前资源的子资源的权限，如果有，
			// 递归调用拥有的那个资源toTree方法，将结果放到children中，
			if(StringUtils.equals(user.getUsername(),"admin")||
					resourceIds.contains(child.getId())){
				children.add(child.toTree(user));
			}
		}
		resource.setChilds(children);
		return resource;
	}
	
	public void addChild(Resource child) {
		childs.add(child);
		child.setParent(this);
	}
	/**
	 * 序号
	 */
	private int sort;


	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<String> getUrls() {
		return urls;
	}

	public void setUrls(Set<String> urls) {
		this.urls = urls;
	}

	@ApiIgnore
	public Resource getParent() {
		return parent;
	}

	public void setParent(Resource parent) {
		this.parent = parent;
	}

	@ApiIgnore
	public List<Resource> getChilds() {
		return childs;
	}

	public void setChilds(List<Resource> childs) {
		this.childs = childs;
	}

	public int getSort() {
		return sort;
	}

	public void setSort(int sort) {
		this.sort = sort;
	}

	/**
	 * @return the link
	 */
	public String getLink() {
		return link;
	}

	/**
	 * @param link the link to set
	 */
	public void setLink(String link) {
		this.link = link;
	}

	/**
	 * @return the icon
	 */
	public String getIcon() {
		return icon;
	}

	/**
	 * @param icon the icon to set
	 */
	public void setIcon(String icon) {
		this.icon = icon;
	}

	/**
	 * @return the type
	 */
	public ResourceType getType() {
		return type;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(ResourceType type) {
		this.type = type;
	}

	@Override
	public int hashCode() {
		return name.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		return this.toString().equals(obj.toString());
	}

	@Override
	public String toString() {
		return name;
	}
}
